
package vip.xiaonuo.biz.modular.lancerCoupon.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.biz.modular.lancerBrand.service.BizBrandService;
import vip.xiaonuo.biz.modular.lancerGoodsBox.service.BizGoodsBoxService;
import vip.xiaonuo.biz.modular.lancerUsercoupon.entity.BizUserCoupon;
import vip.xiaonuo.biz.modular.lancerUsercoupon.service.BizUserCouponService;
import vip.xiaonuo.biz.modular.pojo.domain.BizBrand;
import vip.xiaonuo.biz.modular.pojo.domain.BizGoodsBox;
import vip.xiaonuo.biz.modular.service.LancerLock;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.biz.modular.lancerCoupon.entity.BizCoupon;
import vip.xiaonuo.biz.modular.lancerCoupon.mapper.BizCouponMapper;
import vip.xiaonuo.biz.modular.lancerCoupon.param.BizCouponAddParam;
import vip.xiaonuo.biz.modular.lancerCoupon.param.BizCouponEditParam;
import vip.xiaonuo.biz.modular.lancerCoupon.param.BizCouponIdParam;
import vip.xiaonuo.biz.modular.lancerCoupon.param.BizCouponPageParam;
import vip.xiaonuo.biz.modular.lancerCoupon.service.BizCouponService;

import java.util.List;

/**
 * 优惠券表Service接口实现类
 *
 * @author Lancer
 * @date  2024/03/03 16:29
 **/
@Service
public class BizCouponServiceImpl extends ServiceImpl<BizCouponMapper, BizCoupon> implements BizCouponService {
    @Override
    public Page<BizCoupon> pageClient(BizCouponPageParam bizCouponPageParam) {
        QueryWrapper<BizCoupon> queryWrapper = new QueryWrapper<>();
        queryWrapper.ge("use_end_time", DateUtil.now());
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Autowired
    BizUserCouponService userCouponService;

    @Autowired
    LancerLock lancerLock;
    @Override
    @Transactional
    public void grab(String id) {
        String lockStr="_coupon_"+id;
        try{
            //TODO: 加分布式锁
            String id1 = StpLoginUserUtil.getLoginUser().getId();
            boolean acquire = lancerLock.acquire(lockStr);
            if (acquire){
                // 优惠券减一
                // 获取当前的优惠券数量
                redCouponNumber(id);

                // 优惠券id
                BizUserCoupon userCoupon = new BizUserCoupon();
                userCoupon.setCouponId(id).setUserId(id1);
                userCouponService.save(userCoupon);
            }
            throw new CommonException("抢券失败，请重试！");
        }
        finally {
            lancerLock.release(lockStr);
        }

    }

    @Override
    public void redCouponNumber(String id, Integer currNumber) {
        this.getBaseMapper().redCouponNumber(currNumber,id);
    }

    @Override
    public List<BizCoupon> getCouponListByGoodsBoxId(String goodsBoxId) {
        LambdaQueryWrapper<BizCoupon> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(BizCoupon::getGoodsBoxId,goodsBoxId);
        return this.list(queryWrapper);
    }



    public void redCouponNumber(String id){
        BizCoupon coupon = this.getById(id);
        Integer currNumber = coupon.getCurrNumber();
        this.getBaseMapper().redCouponNumber(currNumber,id);
    }

    @Override
    public Page<BizCoupon> page(BizCouponPageParam bizCouponPageParam) {
        QueryWrapper<BizCoupon> queryWrapper = new QueryWrapper<>();
        if(ObjectUtil.isNotEmpty(bizCouponPageParam.getBrandName())) {
            queryWrapper.lambda().like(BizCoupon::getBrandName, bizCouponPageParam.getBrandName());
        }
        if(ObjectUtil.isNotEmpty(bizCouponPageParam.getGoodsBoxName())) {
            queryWrapper.lambda().like(BizCoupon::getGoodsBoxName, bizCouponPageParam.getGoodsBoxName());
        }
        if(ObjectUtil.isNotEmpty(bizCouponPageParam.getStartUseStartTime()) && ObjectUtil.isNotEmpty(bizCouponPageParam.getEndUseStartTime())) {
            queryWrapper.lambda().between(BizCoupon::getUseStartTime, bizCouponPageParam.getStartUseStartTime(), bizCouponPageParam.getEndUseStartTime());
        }
        if(ObjectUtil.isAllNotEmpty(bizCouponPageParam.getSortField(), bizCouponPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(bizCouponPageParam.getSortOrder());
            queryWrapper.orderBy(true, bizCouponPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(bizCouponPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByAsc(BizCoupon::getId);
        }
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }
    @Override
    public Page<BizCoupon> pageBus(BizCouponPageParam bizCouponPageParam) {
        QueryWrapper<BizCoupon> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(BizCoupon::getBrandId,StpLoginUserUtil.getLoginUser().getId());
        if(ObjectUtil.isNotEmpty(bizCouponPageParam.getBrandName())) {
            queryWrapper.lambda().like(BizCoupon::getBrandName, bizCouponPageParam.getBrandName());
        }
        if(ObjectUtil.isNotEmpty(bizCouponPageParam.getGoodsBoxName())) {
            queryWrapper.lambda().like(BizCoupon::getGoodsBoxName, bizCouponPageParam.getGoodsBoxName());
        }
        if(ObjectUtil.isNotEmpty(bizCouponPageParam.getStartUseStartTime()) && ObjectUtil.isNotEmpty(bizCouponPageParam.getEndUseStartTime())) {
            queryWrapper.lambda().between(BizCoupon::getUseStartTime, bizCouponPageParam.getStartUseStartTime(), bizCouponPageParam.getEndUseStartTime());
        }
        if(ObjectUtil.isAllNotEmpty(bizCouponPageParam.getSortField(), bizCouponPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(bizCouponPageParam.getSortOrder());
            queryWrapper.orderBy(true, bizCouponPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(bizCouponPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByAsc(BizCoupon::getId);
        }
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }
    @Autowired
    BizBrandService brandService;
    @Autowired
    BizGoodsBoxService bizGoodsBoxService;
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(BizCouponAddParam dto) {
        // 获取品牌名称
        BizBrand brandByUserId = brandService.getBrandByUserId();
        if (ObjectUtil.isEmpty(brandByUserId)){
            throw new CommonException("当前用户没有所属品牌，优惠券操作失败！");
        }
        // 获取当前品牌下的商品盒子
        List<BizGoodsBox> bizGoodsBoxes=bizGoodsBoxService.getListByBrandId(brandByUserId.getId());
        if (ObjectUtil.isEmpty(bizGoodsBoxes)){
            throw new CommonException("当前品牌没有任何的商品盒子，无法创建优惠券");
        }
        String goodsBoxName = bizGoodsBoxService.getObjById(dto.getGoodsBoxId()).getGoodsBoxName();
        BizCoupon bizCoupon = BeanUtil.toBean(dto, BizCoupon.class);
        bizCoupon.setBrandId(brandByUserId.getId())
                .setBrandName(brandByUserId.getBrandName())
                .setGoodsBoxId(dto.getGoodsBoxId())
                .setGoodsBoxName(goodsBoxName)
                .setOriginNumber(dto.getOriginNumber())
                .setCurrNumber(dto.getOriginNumber());
        this.save(bizCoupon);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(BizCouponEditParam dto) {
        // 获取原来数据的当前数量
        BizCoupon coupon = this.getById(dto.getId());
        Integer oldCurrNumber = coupon.getCurrNumber();
        Integer oldOriginNumber = coupon.getOriginNumber();
        Integer originNumber = dto.getOriginNumber();

        if (oldCurrNumber-originNumber<0){
            throw new CommonException("原始数量只能增，不能减！");
        }
        BizCoupon bizCoupon = this.queryEntity(dto.getId());
        BeanUtil.copyProperties(dto, bizCoupon);
        bizCoupon.setCurrNumber(oldCurrNumber+originNumber-oldOriginNumber);
        this.updateById(bizCoupon);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void editBus(BizCouponEditParam dto) {
        BizBrand brandByUserId = brandService.getBrandByUserId();
        if (ObjectUtil.isEmpty(brandByUserId)){
            throw new CommonException("当前用户没有所属品牌，优惠券操作失败！");
        }
        // 获取原来数据的当前数量
        BizCoupon coupon = this.getById(dto.getId());
        Integer oldCurrNumber = coupon.getCurrNumber();
        Integer oldOriginNumber = coupon.getOriginNumber();
        Integer originNumber = dto.getOriginNumber();

        if (oldCurrNumber-originNumber<0){
            throw new CommonException("原始数量只能增，不能减！");
        }
        BizCoupon bizCoupon = this.queryEntity(dto.getId());
        BeanUtil.copyProperties(dto, bizCoupon);
        bizCoupon.setCurrNumber(oldCurrNumber+originNumber-oldOriginNumber);
        this.updateById(bizCoupon);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<BizCouponIdParam> bizCouponIdParamList) {
        // 执行删除
        this.removeByIds(CollStreamUtil.toList(bizCouponIdParamList, BizCouponIdParam::getId));
    }

    @Override
    public BizCoupon detail(BizCouponIdParam bizCouponIdParam) {
        return this.queryEntity(bizCouponIdParam.getId());
    }

    @Override
    public BizCoupon queryEntity(String id) {
        BizCoupon bizCoupon = this.getById(id);
        if(ObjectUtil.isEmpty(bizCoupon)) {
            throw new CommonException("优惠券不存在，id值为：{}", id);
        }
        return bizCoupon;
    }


}
